#!/usr/bin/env python
#coding=utf-8
#jk409@qq.com
import sys
#reload(sys)
#sys.setdefaultencoding('utf-8')
sys.path.append('./mymd')
import os,sys,json,time,datetime
from bottle import request,route,error,run,default_app
from bottle import template,static_file,redirect,abort
#import bottle
import logging
from beaker.middleware import SessionMiddleware
from bottle import TEMPLATE_PATH
from gevent import monkey;monkey.patch_all()
import hashlib
from mymd import sql
from math import ceil
#定义app
app = default_app()

#实例化MySQL
db=sql.Mysql('127.0.0.1','root','123456','blog',3306)

#密码加密
def sha256_encryption(args):
    m = hashlib.sha256()
    m.update(args.encode())
    return m.hexdigest()

#获取本脚本所在的路径
pro_path = os.path.split(os.path.realpath(__file__))[0]
sys.path.append(pro_path)

#定义assets路径，即静态资源路径，如css,js,及样式中用到的图片等
static_path = '/'.join((pro_path,'static'))

#定义图片路径
images_path = '/'.join((pro_path,'images'))

#定义提供文件下载的路径
download_path = '/'.join((pro_path,'download'))

#定义文件上传存放的路径
upload_path = '/'.join((pro_path,'upload'))

#定义模板路径
TEMPLATE_PATH.append('/'.join((pro_path,'templates')))

#定义日志目录
log_path = ('/'.join((pro_path,'log')))

#定义日志输出格式
logging.basicConfig(level=logging.INFO,
        format = '%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s',
        datefmt = '%Y-%m-%d %H:%M:%S',
        filename = "%s/access_log.txt" % log_path,
        filemode = 'a')

#设置session参数
session_opts = {
    'session.type':'file',
    'session.cookei_expires':3600,
    'session.data_dir':'sessions',
    'sessioni.auto':True
    }

def checkLogin(fn):
    """验证登陆，如果没有登陆，则跳转到login页面"""
    def BtnPrv(*args,**kw):
        s = request.environ.get('beaker.session')
        if not s.get('userid',None):
            return redirect('/login')
        return fn(*args,**kw)
    return BtnPrv

def checkAccess(fn):
    """验证权限，如果非管理员权限，则返回404页面"""
    def BtnPrv(*args,**kw):
        s = request.environ.get('beaker.session')
        if not s.get('userid',None):
            return redirect('/login')
        elif s.get('userrole',None) != 1:
            abort(403)
        return fn(*args,**kw)
    return BtnPrv

@error(403)
def error403(error):
    """定制错误页面"""
    return template('403')

@error(404)
def error404(error):
    """定制错误页面"""
    return template('404')

@error(500)
def error500(error):
    """定制错误页面"""
    return template('500')

@error(502)
def error502(error):
    """定制错误页面"""
    return template('502')


@route('/static/<filename:re:.*\.css|.*\.js|.*\.png|.*\.jpg|.*\.gif>')
def server_static(filename):
    """定义/assets/下的静态(css,js,图片)资源路径"""
    return static_file(filename, root=static_path)

@route('/static/<filename:re:.*\.ttf|.*\.otf|.*\.eot|.*\.woff|.*\.svg|.*\.map>')
def server_static(filename):
    """定义/assets/字体资源路径"""
    return static_file(filename, root=static_path)


@route('/login',method=['GET','POST'])
def login():
    if request.method=='GET':
        s = request.environ.get('beaker.session')
        if s.get('userid'):
            return redirect('/')
        return template('login', msg='')

    if request.method=='POST':
        print(request.forms.get('email'))
        #---------------------------------------------get
        #name=request.GET.get('name')
        #name=request.query['username']
        #name=request.query.username
        #---------------------------------------------post
        #name = request.forms.get('email')
        #postValue = bottle.request.POST.decode('utf-8')
        #name=request.POST.get('username')


        email = request.forms.get('email').strip()
        passwd = request.forms.get('passwd').strip()
        msg = ''
        if not email or not passwd:
            msg = u'帐号或密码不能为空！'
            return template('login', mes=msg)

        passwd_256 = sha256_encryption(passwd)
        print(passwd_256)
        auth_sql = 'SELECT id,name,role FROM user WHERE email=%s and passwd=%s'
        auth_user = db.read(auth_sql, (email, passwd_256))
        print(auth_user)
        if auth_user:
            s = request.environ.get('beaker.session')
            s['username'] = auth_user[0]['name']
            s['userid'] = auth_user[0]['id']
            s['userrole'] = auth_user[0]['role']
            s.save()
        else:
            msg = u'帐号或密码错误！'
            return template('login', msg=msg)
        return redirect('/')


@route('/logout')
@checkLogin
def logout():
    """退出系统"""
    s = request.environ.get('beaker.session')
    user = s.get('userid',None)
    try:
        s.delete()
    except Exception:
        pass
    return redirect('/')

@route('/passwd/update',method=['GET','POST'])
@checkLogin
def passwd_update():
    s = request.environ.get('beaker.session')
    if request.method == 'GET':
        cates = db.read('select * from cate')
        cname = 'passwd_update'
        msg = ''
        return template('blog_passwd_update', s=s, cname=cname, cates=cates, msg=msg)

    if request.method == 'POST':
        cates = db.read('select * from cate')
        cname = 'passwd_update'
        ids = s.get('userid')
        old_passwd = request.forms.get('old_passwd').strip()
        new_passwd = request.forms.get('new_passwd').strip()
        re_new_passwd = request.forms.get('re_new_passwd').strip()
        new_passwd = sha256_encryption(new_passwd) if new_passwd == re_new_passwd else ''
        old_passwd = sha256_encryption(old_passwd)
        old_res = db.read('select id from user where id=%s and passwd=%s', (ids, str(old_passwd)))
        # print old_passwd
        # print new_passwd
        # print "update user set `passwd`=%s where `id`=%s", (str(new_passwd),ids)
        if new_passwd and old_res:
            res = db.write("update user set `passwd`=%s where `id`=%s", (str(new_passwd), ids))
            if res:
                s.delete()
                return redirect('/')
        msg = '密码修改失败！'
        return template('blog_passwd_update', s=s, cname=cname, cates=cates, msg=msg)


@route('/')
def index():
    return redirect('/new')

@route('/new')
@route('/new/<page>')
def news(page=1):
    logging.info('access /hot')
    page = int(page)
    cname='new'
    s = request.environ.get('beaker.session')
    print(s)
    dbs = db.read('select id from title')
    cates=db.read('select * from cate')
    total_number = float(len(dbs))
    page_number = 6
    total_page = ceil(total_number / page_number)
    if page > total_page: page = total_page
    if page < 1:
        number_s = 0
    else:
        number_s = (page - 1) * page_number
    sqls = 'select  `id`,`tname`,`name`,`tag`,`read`,`review`,`like`,`ctime`,`mtime` from title order by `ctime` desc limit %s,%s'
    res = db.read(sqls, (number_s, page_number))
    for i in res:
        i['ctime'] = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(i['ctime']))
    return template('index',s=s,res=res,total_page=int(total_page),page=page,cname=cname,url_s='new',cates=cates)

@route('/hot')
@route('/hot/<page>')
def hots(page=1):
    logging.info('access /hot')
    cname='hot'
    page = int(page)
    s = request.environ.get('beaker.session')
    dbs = db.read('select id from title')
    cates = db.read('select * from cate')
    total_number = float(len(dbs))
    page_number = 6
    total_page = ceil(total_number / page_number)
    if page > total_page: page = total_page
    if page < 1: number_s = 0
    else:number_s = (page - 1) * page_number
    sqls='select  `id`,`tname`,`name`,`tag`,`read`,`review`,`like`,`ctime`,`mtime` from title order by `read` desc limit %s,%s'
    res = db.read(sqls, (number_s, page_number))
    for i in res:
        i['ctime'] = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(i['ctime']))
    return template('index', s=s, res=res, total_page=int(total_page), page=page, cname=cname, url_s='hot', cates=cates)

@route('/cate/<cname>/<cid>/<page>')
def default(cname='default',page=1,cid=0):
    logging.info('access /cate/%s'%cname)
    page = int(page)
    cid=cid
    url_s='cate/%s'%cname
    s = request.environ.get('beaker.session')
    #
    dbs = db.read("select id from title where cid=%s"%cid)
    cates = db.read('select * from cate')
    total_number = float(len(dbs))
    page_number = 6
    total_page = ceil(total_number / page_number)
    print(total_page)
    if page > total_page: page = total_page
    if page < 1: number_s = 0
    else:number_s = (page - 1) * page_number
    #
    sqls='''
    select `t`.`id`,`t`.`tname`,`t`.`name`,`t`.`tag`,`t`.`read`,`t`.`review`,`t`.`like`,`t`.`ctime`,`t`.`mtime`
    from title as t
    where t.cid=%s
    order by `t`.`ctime` desc
    limit %s,%s
    '''
    res = db.read(sqls, (cid,number_s, page_number))
    for i in res:
        i['ctime'] = time.strftime("%Y-%m-%d %H-%M-%S", time.localtime(i['ctime']))
    return template('blog_cate', s=s, res=res,total_page=int(total_page),cid=cid,url_s=url_s,cates=cates,cname=cname,page=page)

@route('/content/<ids>')
def content(ids=0):
    ids=int(ids)
    logging.info('access /content/%s' % ids)
    s = request.environ.get('beaker.session')
    #
    db.write('update title set `read`=`read`+1 where id=%s;',ids)
    cates = db.read('select * from cate')
    res=db.read('select * from title where id=%s',ids)
    for i in res:
        i['ctime'] = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(i['ctime']))
        break
    return template('blog', s=s, res=res, cates=cates, cname='contents')


@route('/admin')
@route('/admin/<page>')
@checkLogin
@checkAccess
def admin(page=1):
    logging.info('access /hot')
    page = int(page)
    cname='admin'
    s = request.environ.get('beaker.session')
    dbs = db.read('select id from title')
    cates=db.read('select * from cate')
    total_number = float(len(dbs))
    page_number = 6
    total_page = ceil(total_number / page_number)
    if page > total_page: page = total_page
    if page < 1:
        number_s = 0
    else:
        number_s = (page - 1) * page_number
    sqls = 'select  `id`,`tname`,`name`,`read`,`review`,`like`,`ctime` from title order by `ctime` desc limit %s,%s'
    res = db.read(sqls, (number_s, page_number))
    for i in res:
        i['ctime'] = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(i['ctime']))
    return template('admin',s=s,res=res,total_page=int(total_page),page=page,cname=cname,url_s='new',cates=cates)


@route('/admin/content/add',method=['GET','POST'])
@checkLogin
@checkAccess
def admin_add_content():
    s = request.environ.get('beaker.session')
    if request.method=='GET':
        cname = 'admin'
        cates = db.read('select * from cate')
        return template('blog_add', s=s, cname=cname, cates=cates)

    if request.method=='POST':
        req = request.POST.decode('utf-8')
        title  =req.get('title')
        cate_id=req.get('cate_id')
        tag    =req.get('tag')
        comment=req.get('comment')
        tms=int(time.time())
        if title and comment:
            sqls='''
                INSERT INTO `blog`.`title` (`cid`, `tname`, `name`, `content`, `ctime`, `mtime`) VALUES (%s, %s, %s, %s, %s, %s);
            '''
            db.write(sqls,(int(cate_id),title,str(s['userid']),comment,tms,tms))
        return redirect('/admin')


@route('/admin/content/edit/<ids>',method=['GET','POST'])
@checkLogin
@checkAccess
def admin_edit_content(ids=0):
    ids=int(ids)
    if ids == 0: return redirect('/admin')
    s = request.environ.get('beaker.session')
    if request.method == 'GET':
        cname = 'content'
        cates = db.read('select * from cate')
        res = db.read('select * from title where id=%s', ids)
        return template('blog_edit', s=s, cname=cname, cates=cates, res=res)

    if request.method == 'POST':
        req = request.POST.decode('utf-8')
        tname = req.get('title')
        cate_id = req.get('cate_id')
        tag = req.get('tag')
        comment = req.get('comment')
        tms = int(time.time())
        if tname and comment:
            sqls = '''
                UPDATE `blog`.`title`
                SET `cid`=%s,
                    `tname`=%s,
                    `name`=%s,
                    `content`=%s,
                    `mtime`=%s
                WHERE `id`=%s;
            '''
            db.write(sqls, (int(cate_id), tname, str(s['userid']), comment, tms,ids))
        return redirect('/admin')


@route('/admin/content/delete/<ids>')
@checkLogin
@checkAccess
def admin_content_delete(ids=0):
    if ids:
        db.write('delete from title where `id`=%s', int(ids))
    return redirect('/admin')


@route('/test',method=['get','post'])
def test():
    if request.method=='GET':
        print('GET')
        return '''
        <form action='/test' method="post">
        <input type="text" name='name' />
        <button type="submit">提交</button>
        </form>
        '''
    if request.method == 'POST':
        print(request.forms.get('name'))
        return  'POST'



if __name__=="__main__":
    app = SessionMiddleware(app, session_opts)
    run(app=app,host='0.0.0.0', port=8080,reloader=True,server='gevent')